#ifndef _XX_YY_BMOCK_RESULT
#define _XX_YY_BMOCK_RESULT
#include <boost/shared_ptr.hpp>
#include "detail/bmock_any.hpp"
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include "detail/bmock_raw_mem.hpp"

namespace bmock {
	struct result {
		virtual bmock_any get_value() const = 0;
		virtual ~result() {}
	};

	struct void_result : public result {
		bmock_any get_value() const {
			throw this;
		}
		~void_result() {}
	};

	typedef boost::shared_ptr<const result> result_ptr;

	struct exception_result : public result {
		bmock_any get_value() const {
			throw this;
		}
		virtual void throw_exception() const = 0;
		virtual ~exception_result(){}
	};

	template<typename E>
	struct exception_result_imp : public exception_result {
		exception_result_imp(const E *const e)
			:p_exception_(e)
		{}
		void throw_exception() const {
			throw *p_exception_;
		}
		~exception_result_imp() {}
	private:
		boost::shared_ptr<const E> p_exception_;
	};
	template<typename E>
	inline const exception_result_imp<E> *const create_exception(const E* const e) {
		return new exception_result_imp<E>(e);
	}
	struct value_result : public result {
		value_result(const bmock_any &v) 
			:value_(v)
		{}
		bmock_any get_value() const {
			return value_;
		}
		~value_result() {}
	private:
		bmock_any value_;
	};		
};

#endif
